package com.homevip.core.dao;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.TypedQuery;

import com.homevip.core.page.Page;
import com.homevip.core.page.Pageable;

/**
 * select new 查询
 * @author ll
 *
 * @param <T>
 */
public class QueryToVo<T> {
	
	private Class<T> voClass;	// Vo类
	private EntityManager em;	// 实体管理
	private String select;		// 查询子句
	private String from;		// 表子句
	private QueryWhere where;	// 条件
	private String groupBy;		// 分组子句

	public QueryToVo(EntityManager em, Class<T> voClass) {

		this.em = em;
		this.voClass = voClass;
	}
	
	public QueryToVo<T> select(String select) {
		
		this.select = select;
		return this;
	}
	
	public QueryToVo<T> from(String from) {
		
		this.from = from;
		return this;
	}

	public QueryToVo<T> where(QueryWhere where) {
		
		this.where = where;
		return this;
	}

	public QueryToVo<T> groupBy(String by) {
		
		this.groupBy = by;
		return this;
	}
	
	/**
	 * 创建查询
	 * @param pageable 分页
	 * @return
	 */
	private TypedQuery<T> createQuery(Pageable pageable) {
		
		//JPQL
		StringBuilder ql = new StringBuilder(256);
		ql.append("select new ").append(voClass.getName()).append('(');
		ql.append(this.select).append(") from ").append(this.from);
		if (null != where && where.hasWhere()) {
			
			ql.append(" where ");
			where.toQL(ql, null, 1);
		}
		if (null != this.groupBy) ql.append(" group by ").append(this.groupBy);
		if (null != pageable && null != pageable.getSort())
			ql.append(pageable.getSort().toQL(null));// 排序
		
		// 查询
		TypedQuery<T> query = em.createQuery(ql.toString(), voClass);
		if (null != where && where.hasWhere()) where.toParameters(query);
		
		return query;
	}

	/**
	 * 取列表
	 * @return
	 */
	public List<T> getResultList() {

		TypedQuery<T> query = createQuery(null);
		return query.getResultList();
	}

	/**
	 * 分页取结果
	 * @param total 总记录数
	 * @param pageable 分页
	 * @return
	 */
	public Page<T> getPage(int total, Pageable pageable) {

		TypedQuery<T> query = createQuery(pageable);
		query.setMaxResults(pageable.getPageSize());
		query.setFirstResult(pageable.getOffset());
		return new Page<T>(query.getResultList(), pageable, total);
	}
}